package main

import (
	"github.com/go-gl/gl/v2.1/gl"
	mgl "github.com/go-gl/mathgl/mgl32"
	"github.com/go-gl/glfw/v3.2/glfw"
	"gogl/array"
	"gogl/shader"
	"math"
)
var light *Light
var lightPos mgl.Vec3
type Light struct{
	prog *shader.Program
	vao,vbo uint32
	points []float32
	indices []uint32
}
func (l *Light) construct(){
	l.setShaderSource()
	l.makeVao()
}

func (l *Light) draw(){
	projection := ca.GetProjection()
	view := ca.GetViewMatrix()
	prog := l.prog.Use()
	lightPos = mgl.Vec3{1.2,float32(math.Sin(glfw.GetTime())),2}
	lightPosTranslate := mgl.Translate3D(lightPos.X(),lightPos.Y(),lightPos.Z())
	model := lightPosTranslate.Mul4(mgl.Scale3D(0.2,0.2,0.2))
	prog.Bind4fv("model",1,false,&model[0])
	prog.Bind4fv("view",1,false,&view[0])
	prog.Bind4fv("projection",1,false,&projection[0])
	gl.BindVertexArray(l.vao)
	gl.DrawElements(gl.TRIANGLES,int32(len(l.indices)),gl.UNSIGNED_INT,nil)
}

func (l *Light) setShaderSource(){
	const (
		vertexShaderSource = `
        #version 120
		 attribute vec3 vp;
        attribute vec3 aColor;
		 attribute vec2 aTexCoords;
		 attribute vec3 aNormal;
		 uniform mat4 model;
		 uniform mat4 view;
		 uniform mat4 projection;
        void main() {
			gl_Position = projection*view*model*vec4(vp, 1.0);
        }
    ` + "\x00"

		fragmentShaderSource = `
        #version 120
        void main() {
			gl_FragColor = vec4(1.0);
        }
    ` + "\x00"
	)
	//顶点着色器
	vertexShader, err := shader.CompileShader(vertexShaderSource, gl.VERTEX_SHADER)
	if err != nil {
		panic(err)
	}
	fragmentShader, err := shader.CompileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
	if err != nil {
		panic(err)
	}

	l.prog = shader.NewProgram(vertexShader,fragmentShader)
	//编译完成后需要删除着色器
	gl.DeleteShader(vertexShader)
	gl.DeleteShader(fragmentShader)
}
//索引缓冲
func (l *Light) makeVao(){

	var (
		points = []float32{
			0.5, 0.5, 0.5, 	1.0, 0.0, 0.0,   1.0, 1.0,	0,0,0,// 右上角
			0.5, -0.5, 0.5,  0.0, 1.0, 0.0,  1.0,0.0,   0,0,0,// 右下角
			-0.5, -0.5, 0.5,  0.0, 0.0, 1.0, 0.0,0.0, 	0,0,0,// 左下角
			-0.5, 0.5,0.5,   0.0, 0.0, 1.0,  0.0,1.0,   0,0,0,// 左上角
			0.5, 0.5, -0.5,  1.0, 0.0, 0.0,   1.0, 1.0, 0,0,0,// 右上角
			0.5, -0.5, -0.5,  0.0, 1.0, 0.0,  1.0,0.0, 	0,0,0,// 右下角
			-0.5, -0.5, -0.5,  0.0, 0.0, 1.0, 0.0,0.0, 	0,0,0,// 左下角
			-0.5, 0.5,-0.5,   0.0, 0.0, 1.0,  0.0,1.0, 	0,0,0,// 左上角
		};
		indices = []uint32{
			0, 1, 3,
			1, 2, 3,
			1, 2, 5,
			2, 5, 6,
			2, 6, 3,
			3, 6, 7,
			3, 4, 7,
			0, 3, 4,
			0, 4, 5,
			0, 1, 5,
			4, 6, 7,
			4, 5, 6,
		};
	)
	var slice_len int32 = 11
	array.GetIndicesNormal(&points,indices,slice_len,8,9,10)
	var vbo uint32
	var ebo uint32
	gl.GenBuffers(1,&vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
	gl.BufferData(gl.ARRAY_BUFFER,4*len(points), gl.Ptr(points), gl.STATIC_DRAW)
	gl.GenBuffers(1,&ebo)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER,4*len(indices), gl.Ptr(indices), gl.STATIC_DRAW)
	var vao uint32

	gl.GenVertexArrays(1,&vao)
	gl.BindVertexArray(vao)
	gl.BindBuffer(gl.ARRAY_BUFFER,vbo)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER,ebo)


	prog := l.prog
	prog.SetTotalAttributeNum(slice_len)

	prog.BindAttribute("vp",3)
	prog.BindAttribute("aColor",3)
	prog.BindAttribute("aTexCoords",2)
	prog.BindAttribute("aNormal",3)

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

	l.vao = vao
	l.vbo = vbo
	l.points = points
	l.indices = indices
}

func DrawLight(){
	if light == nil{
		light = &Light{}
		light.construct()
	}
	light.draw()
}

func DestroyLight() {
	gl.DeleteVertexArrays(1,&light.vao)
	gl.DeleteBuffers(1,&light.vbo)
}




